package com.ray.friendslist.http;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import com.ray.friendslist.token.VkTokenManager;

public class HttpManager {

	private HttpClient mClient;

	private final String API_URL = "https://api.vk.com/method/";

	private static HttpManager instance;

	private HttpManager() {
	}

	public static HttpManager getInstance() {
		if (instance == null) {
			instance = new HttpManager();
		}
		return instance;
	}

	public Bitmap loadBitmap(String url) throws MalformedURLException,
			IOException {
		InputStream openStream = new URL(url).openStream();
		//TODO close os
		return BitmapFactory.decodeStream(openStream);
	}

	public String postRequest(String methodName,
			ArrayList<BasicNameValuePair> params)
			throws ClientProtocolException, IOException, JSONException {
		HttpPost post = new HttpPost(API_URL + methodName);
		params.add(new BasicNameValuePair("access_token", VkTokenManager
				.getTooken()));
		UrlEncodedFormEntity ent = new UrlEncodedFormEntity(params, HTTP.UTF_8);
		post.setEntity(ent);
		mClient = new DefaultHttpClient();
		HttpResponse response = mClient.execute(post);
		if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
			String entityValue = null;
			entityValue = EntityUtils.toString(response.getEntity());
			throw new IOException(response.getStatusLine().getReasonPhrase()
					+ " " + entityValue + " "
					+ response.getStatusLine().getStatusCode());
		}
		return response.toString();
	}

	public String loadAsString(String url) throws ClientProtocolException,
			IOException, JSONException {
		return loadAsString(new HttpGet(url));
	}

	public JSONArray loadAsJsonArray(String url)
			throws ClientProtocolException, JSONException, IOException {
		return new JSONArray(loadAsString(url));
	}

	public JSONObject loadAsJSONObject(String url)
			throws ClientProtocolException, JSONException, IOException {
		return new JSONObject(loadAsString(url));
	}

	private String loadAsString(HttpRequestBase request)
			throws ClientProtocolException, IOException, JSONException {
		mClient = new DefaultHttpClient();
		HttpResponse response = mClient.execute(request);
		if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
			String entityValue = null;
			entityValue = EntityUtils.toString(response.getEntity());
			throw new IOException(response.getStatusLine().getReasonPhrase()
					+ " " + entityValue + " "
					+ response.getStatusLine().getStatusCode());
		}
		final InputStream is = new URL(request.getURI().toString())
				.openStream();
		try {
			final BufferedReader rd = new BufferedReader(new InputStreamReader(
					is, Charset.forName("UTF-8")));
			final String jsonText = readAll(rd);
			// Log.w("ray","HTTp:"+ jsonText);
			return jsonText;
		} finally {
			is.close();
		}

	}

	private static String readAll(final Reader rd) throws IOException {
		final StringBuilder sb = new StringBuilder();
		int cp;
		while ((cp = rd.read()) != -1) {
			sb.append((char) cp);
		}
		// Log.w("ray","HTTp"+ sb.toString());
		return sb.toString();
	}
}
